/*
* Copyright (c) 2016 bond. All Rights Reserved.
*/
package net.xiake6.springcloud.gateway.gateway;
import com.google.common.base.Strings;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 类或方法的功能描述 :TODO
 *
 * @author:
 * @date: 2017-10-23 下午9:36
 */
@Component
public class GenericZuulFallbackProvider implements FallbackProvider {

    private String responseBody = "";
    private HttpHeaders headers = null;
    private String route = "";
    private int rawStatusCode = 503;
    private HttpStatus statusCode = HttpStatus.SERVICE_UNAVAILABLE;
    private String statusText = "Service Unavailable";

    @Override
    public String getRoute() {
        return route;
    }


    /**
     * 熔断器会调用下面的fallbackResponse方法,最终模拟返回一个ClientHttpResponse.
     * 里面包含HttpHeaders、rawStatusCode、statusCode和responseBody等信息,这些信息都可以自定义返回值.
     * MediaType则包含多种返回信息的格式Json、Pdf、Image等等.
     *
     * @see org.springframework.cloud.netflix.zuul.filters.route(
     */
    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new ClientHttpResponse() {
            @Override
            public InputStream getBody() throws IOException {
                String resultData="";
                if(!Strings.isNullOrEmpty(responseBody)){
                    resultData="{\"resCode\":503,\"resDes\":\""+responseBody+"\"}";
                }else {
                    resultData="{\"resCode\":503,\"resDes\":\""+String.format("%s Unavailable. Please try after sometime",getRoute())+"\"}";
                }

                return new ByteArrayInputStream(resultData.getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                if (headers == null) {
                    headers = new HttpHeaders();
                    headers.setContentType(MediaType.APPLICATION_JSON);
                }
                return headers;
            }

            @Override
            public void close() {

            }

            @Override
            public int getRawStatusCode() throws IOException {
                return rawStatusCode;
            }

            @Override
            public HttpStatus getStatusCode() throws IOException {
                if (statusCode == null) {
//                    statusCode = HttpStatus.SERVICE_UNAVAILABLE;
                    statusCode = HttpStatus.SERVICE_UNAVAILABLE;
                }
                return statusCode;
            }

            @Override
            public String getStatusText() throws IOException {
                if (statusText == null) {
                    statusText = "Service Unavailable";
                }

                return statusText;
            }
        };
    }

    public String getResponseBody() {
        return responseBody;
    }

    public void setResponseBody(String responseBody) {
        this.responseBody = responseBody;
    }

    public HttpHeaders getHeaders() {
        return headers;
    }

    public void setHeaders(HttpHeaders headers) {
        this.headers = headers;
    }

    public int getRawStatusCode() {
        return rawStatusCode;
    }

    public void setRawStatusCode(int rawStatusCode) {
        this.rawStatusCode = rawStatusCode;
    }

    public HttpStatus getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(HttpStatus statusCode) {
        this.statusCode = statusCode;
    }

    public String getStatusText() {
        return statusText;
    }

    public void setStatusText(String statusText) {
        this.statusText = statusText;
    }

    public void setRoute(String route) {
        this.route = route;
    }
}

